'''
Description: 
Author: Zilu
Date: 2021-11-12 14:44:37
Version: 
LastEditTime: 2021-11-12 15:24:58
LastEditors: Zilu
'''

# Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数 
# 甚至可以创建无限序列
import itertools
from typing import overload
naturalOdds = itertools.count(1, 2)
for i in naturalOdds:
    print(i)

cycle = itertools.cycle('ABC')
for c in cycle:
    print(c)

repeat = itertools.repeat('A',4)
for c in repeat:
    print(c)

class altPara(object):
    @overload
    def __init__(self, obj:object) -> None:
        super().__init__()

    @overload
    def __init__(self, obj:object, times:int) -> None:
        super().__init__()

a = altPara()

# 通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列：
ns = itertools.takewhile(lambda x:x<=10, naturalOdds)
list(ns)

# itertools提供的几个迭代器操作函数更加有用
# chain 函数将迭代对象串联，返回一个更大的迭代器
for c in itertools.chain('ABC','XYZ'):
    print(c)

# gruopby 将预测器认为相等的相邻重复元素成组，预测器的返回值作为组的key
for k, g in itertools.groupby('AaaBBbcccAAa', lambda c:c.upper()):
    print(k, list(g))

# 练习：用itertools计算圆周率序列的前N项和
def pi(N:int):
    from functools import reduce
    return reduce(lambda x, y: x + y, 
        [4 / (x if x%4==1 else -x) for x in itertools.takewhile(lambda x: x<=2*N-1, itertools.count(1, 2))])
    

